/*
 * Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package v20190823;

import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.tencentcloudapi.common.AbstractClient;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.JsonResponseModel;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceRequest;
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceResponse;
import sun.misc.BASE64Decoder;
import v20190823.models.CreateTtsTaskRequest;
import v20190823.models.CreateTtsTaskResponse;
import v20190823.models.DescribeTtsTaskStatusRequest;
import v20190823.models.DescribeTtsTaskStatusResponse;

import javax.servlet.ServletOutputStream;
import java.io.*;
import java.lang.reflect.Type;
import java.util.UUID;

public class TtsClient extends AbstractClient{
    private static String endpoint = "tts.tencentcloudapi.com";
    private static String service = "tts";
    private static String version = "2019-08-23";



    public static void main(String[] args) {
        try{
            String basePath="D:\\voice\\我的老千生涯\\";
            String fileName="引子 惊梦，我就是传说中的老千.txt";
            File file = new File(basePath+fileName);
            BufferedReader br= new BufferedReader(new FileReader(file));
            StringBuilder text = new StringBuilder();
            String st = null;
            while ((st = br.readLine()) != null){
                text.append(System.lineSeparator()+st);
            }

            CreateTtsTaskRequest req=new CreateTtsTaskRequest();
            TtsClient.initRequestCreate(req,text.toString());
            Credential cred = new Credential("AKIDRkqjNrBHI8mDSbZQ4UfeYDgutd9TcZP7", "aw4ye4FBsKZeWCftrcT9aoobAUaUBev0");
            TtsClient client=new TtsClient(cred,"ap-shanghai");
            CreateTtsTaskResponse createTtsTaskResponse=client.CreateTtsTask(req);
            String requestId = createTtsTaskResponse.getRequestId();

            int i = fileName.lastIndexOf('.');
            String prefix = fileName.substring(0,i);
            String suffix = fileName.substring(i+1).toLowerCase();
//            String audio = textToVoiceResponse.getAudio();
//            String audioPath=basePath+suffix+"wav";
//            TtsClient.exportImg(audioPath,audio);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    private static void initRequestCreate(CreateTtsTaskRequest req, String text) {

        req.setText(text);

        req.setModelType(Long.valueOf(1));
        //音量大小，范围：[0，10]，分别对应11个等级的音量，默认为0，代表正常音量。没有静音选项。
        //输入除以上整数之外的其他参数不生效，按默认值处理。
        req.setVolume(Float.valueOf(5));
        //语速，范围：[-2，2]，分别对应不同语速：
        //-2代表0.6倍
        //-1代表0.8倍
        //0代表1.0倍（默认）
        //1代表1.2倍
        //2代表1.5倍
        //如果需要更细化的语速，可以保留小数点后一位，例如0.5 1.1 1.8等。
        req.setSpeed(Float.valueOf(0));

        req.setProjectId(Long.valueOf(0));

        req.setVoiceType(Long.valueOf(101001));

        //主语言类型：1-中文（默认） 2-英文
        req.setPrimaryLanguage(Long.valueOf(1));

        //音频采样率： 16000：16k（默认） 8000：8k
        req.setSampleRate(Long.valueOf(16000));

        //返回音频格式，可取值：wav（默认），mp3，pcm
        req.setCodec("mp3");
    }

    private static void initRequest(TextToVoiceRequest req,String text) {

        req.setText(text);

        String sessionId= UUID.randomUUID().toString();
        req.setSessionId(sessionId);

        req.setModelType(Long.valueOf(1));
        //音量大小，范围：[0，10]，分别对应11个等级的音量，默认为0，代表正常音量。没有静音选项。
        //输入除以上整数之外的其他参数不生效，按默认值处理。
        req.setVolume(Float.valueOf(5));
        //语速，范围：[-2，2]，分别对应不同语速：
        //-2代表0.6倍
        //-1代表0.8倍
        //0代表1.0倍（默认）
        //1代表1.2倍
        //2代表1.5倍
        //如果需要更细化的语速，可以保留小数点后一位，例如0.5 1.1 1.8等。
        req.setSpeed(Float.valueOf(0));

        req.setProjectId(Long.valueOf(0));

        req.setVoiceType(Long.valueOf(101001));

        //主语言类型：1-中文（默认） 2-英文
        req.setPrimaryLanguage(Long.valueOf(1));

        //音频采样率： 16000：16k（默认） 8000：8k
        req.setSampleRate(Long.valueOf(16000));

        //返回音频格式，可取值：wav（默认），mp3，pcm
        req.setCodec("wav");



    }


    public TtsClient(Credential credential, String region) {
        this(credential, region, new ClientProfile());
    }

    public TtsClient(Credential credential, String region, ClientProfile profile) {
        super(TtsClient.endpoint, TtsClient.version, credential, region, profile);
    }

    /**
     *本接口服务对10万字符以内的文本进行语音合成，异步返回音频结果。满足一次性合成较长文本的客户需求，如阅读播报、新闻媒体等场景。

<li>支持音频格式：mp3,wav,pcm</li>
<li>支持音频采样率：16000 Hz, 8000 Hz</li>
<li>支持中文普通话、英文、中英文混读、粤语合成</li>
<li>支持语速、音量设置</li>
<li>支持回调或轮询的方式获取结果，结果获取请参考 长文本语音合成结果查询。</li>
<li>长文本语音合成任务完成后，合成音频结果在服务端可保存24小时</li>

<p></p>

长文本合成支持 SSML，语法详见 [SSML 标记语言](https://cloud.tencent.com/document/product/1073/49575)，使用时需满足如下使用规范：
<li>使用 SSML 标签，需置于 speak 闭合标签内部；</li>
<li>合成文本可包含多组 speak 闭合标签，且无数量限制；</li>
<li>每个 speak 闭合标签内部，字符数不超过 150 字（标签字符本身不计算在内）；</li>
<li>每个 speak 闭合标签内部，使用 break 标签数目最大为 10 个。如需要使用更多，可拆解到多个 speak 标签中；</li>

<p></p>
     * @param req CreateTtsTaskRequest
     * @return CreateTtsTaskResponse
     * @throws TencentCloudSDKException
     */
    public CreateTtsTaskResponse CreateTtsTask(CreateTtsTaskRequest req) throws TencentCloudSDKException{
        JsonResponseModel<CreateTtsTaskResponse> rsp = null;
        String rspStr = "";
        try {
                Type type = new TypeToken<JsonResponseModel<CreateTtsTaskResponse>>() {
                }.getType();
                rspStr = this.internalRequest(req, "CreateTtsTask");
                rsp  = gson.fromJson(rspStr, type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException("response message: " + rspStr + ".\n Error message: " + e.getMessage());
        }
        return rsp.response;
    }

    /**
     *在调用长文本语音合成请求接口后，有回调和轮询两种方式获取识别结果。

<li>当采用回调方式时，合成完毕后会将结果通过 POST 请求的形式通知到用户在请求时填写的回调 URL，具体请参见 长文本语音合成结果查询 。</li>
<li>当采用轮询方式时，需要主动提交任务ID来轮询识别结果，共有任务成功、等待、执行中和失败四种结果，具体信息请参见下文说明。</li>
     * @param req DescribeTtsTaskStatusRequest
     * @return DescribeTtsTaskStatusResponse
     * @throws TencentCloudSDKException
     */
    public DescribeTtsTaskStatusResponse DescribeTtsTaskStatus(DescribeTtsTaskStatusRequest req) throws TencentCloudSDKException{
        JsonResponseModel<DescribeTtsTaskStatusResponse> rsp = null;
        String rspStr = "";
        try {
                Type type = new TypeToken<JsonResponseModel<DescribeTtsTaskStatusResponse>>() {
                }.getType();
                rspStr = this.internalRequest(req, "DescribeTtsTaskStatus");
                rsp  = gson.fromJson(rspStr, type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException("response message: " + rspStr + ".\n Error message: " + e.getMessage());
        }
        return rsp.response;
    }

    /**
     *腾讯云语音合成技术（TTS）可以将任意文本转化为语音，实现让机器和应用张口说话。
腾讯TTS技术可以应用到很多场景，比如，移动APP语音播报新闻；智能设备语音提醒；依靠网上现有节目或少量录音，快速合成明星语音，降低邀约成本；支持车载导航语音合成的个性化语音播报。
内测期间免费使用。
基础合成支持 SSML，语法详见 [SSML 标记语言](https://cloud.tencent.com/document/product/1073/49575)。
     * @param req TextToVoiceRequest
     * @return TextToVoiceResponse
     * @throws TencentCloudSDKException
     */
    public TextToVoiceResponse TextToVoice(TextToVoiceRequest req) throws TencentCloudSDKException{
        JsonResponseModel<TextToVoiceResponse> rsp = null;
        String rspStr = "";
        try {
                Type type = new TypeToken<JsonResponseModel<TextToVoiceResponse>>() {
                }.getType();
                rspStr = this.internalRequest(req, "TextToVoice");
                rsp  = gson.fromJson(rspStr, type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException("response message: " + rspStr + ".\n Error message: " + e.getMessage());
        }
        return rsp.response;
    }


    public static void exportImg(String filePath,String audio) {
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            //Base64解码
            byte[] b = decoder.decodeBuffer(audio);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    //调整异常数据
                    b[i] += 256;
                }
            }
            InputStream in = new ByteArrayInputStream(b);
            File f = new File(filePath);// 可以是任何图片格式.jpg,.png等

            FileOutputStream fos = new FileOutputStream(f);
            byte[] b2 = new byte[1024];
            int nRead = 0;
            while ((nRead = in.read(b2)) != -1) {
                fos.write(b2, 0, nRead);
            }
            fos.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
    }

}
